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

Real-time Animated Graphing using Flash MX, Part 2

By Pallav Nadhani


  • Read Part 1

  • In Part 1 we saw examined the basic architecture for FunkyCharts. In this part we'll look specifically at the XML structure used to communicate plotting data from the Web server to the FunkyCharts Flash movie, which runs on the client's computer.

    The XML Structure
    Recall that the FunkyChart flash file, which executes on the client's machine, communicates with the Web server to obtain the data it needs to plot. This data is exchanged in an predefined XML format. An example of this format is given below:

    <graph bgcolor="E1F5FF" caption="Hits for the first half (in thousands)" 
          xaxisname="Month" yaxisname="Hits" yaxisminvalue="0" yaxismaxvalue="50">
       <set name="Jan" value="20" color="3300FF" /> 
       <set name="Feb" value="9" color="FF0000" /> 
       <set name="Mar" value="7" color="009966" /> 
       <set name ="Apr" value="40" color="FFCC00" /> 
       <set name="May" value="23" color="CC0033" /> 
       <set name="Jun" value="34" color="CCCC33" /> 
       <set name="Jul" value="19" color="FF9900" />
    </graph>
    

    As you can see, the root element, <graph>, has a number of attributes worth discussing:

    • bgcolor - specifies the background color of the graph. The bgcolor value is the hexidecimal value of a color without the # prefix.
    • caption - specifies the caption (heading) of the graph, which is displayed on the top of the graph canvas.
    • xaxisname - specifies the x-axis caption of the graph
    • yaxisname - specifies the y-axis caption of the graph
    • yaxisminvalue - determines the y-axis lower limit value - i.e., the origin value for y-axis. This is an optional value as we'll see later. If this value isn't provided to the graph, the graph will automatically select the lowest value provided in the data to be the y-axis lower limit.
    • yaxismaxvalue - determines the y-axis upper limit value - i.e., the maximum value for the y-axis. This is an optional value, in the same manner as the yaxisminvalue attribute

    The <graph> node's attributes merely specify aesthetic settings. The actual plotted data for the graph is contained within individual <set> elements, which is a childnode of the root <graph> element. The attributes used to define the data are:

    • name - The value displayed on the x-axis for the particular data point
    • value - The value displayed on the y-axis for the particular data point
    • color - The color in which this set of data will be displayed.

    Now that we've looked at the format of the data exchanged between the Web server and the Flash movie, let's look at the code needed in the Flash movie to actually render the graph from the XML data.

    Creating the Flash Movie
    A screenshot of a FunkyChart line graph. Before we examine the actual creation of the graph, let's take a second to look at the various visual elements of the graph, so that we know what we're working toward. The screenshot to the right shows the output of a FunkyChart line graph with various pieces of the graph labeled by their attribute name. That is, the caption up at the top, "Hits for the first half (in thousands)," has a red box around it and a label "Graph Caption." Normally this red box and label wouldn't be present in the output - it is included to indicate how the value of the caption attribute of the <graph> node is rendered.

    Now that we know what we are aiming for, start by creating a new Flash movie with the dimensions of 350 px (width) x 300 px (height). Set the fps (Frames per second) to 120. (We increase the fps to increase the speed of animation.) Next, rename the default scene to "Graph". To rename a scene, go to Modify > Scene, click the scene name twice and then rename it.

    In the graph create a background that is a movie clip with a rectangle of size 350 x 300 px. Place an instance of this movie in the main timeline and use ActionScript to change the color of this movie clip by utilizing the color object in Flash. These things can be accomplished by performing the following detailed steps:

    1. To create the movie clip, go to Insert > New Symbol menu.
    2. In the pop-up dialog, enter the Name as MCBg and select the Behaviour as Movie Clip.
    3. You'll be provided with a blank screen. In the default layer and frame provided, draw a rectangle of size 350 x 300 px (using the rectangle drawing tool from the toolbox). Give the rectangle any color which you wish to be initially set as the background, until the XML document has been loaded - after the XML document has been loaded, we will change the color of this movie clip to the one provided in the XML document.
    4. Now, get back to the main timeline i.e., the timeline of Scene Graph.
    5. Rename the default layer to Background
    6. On the frames of this layer, place the newly created movie clip to cover up the entire stage and name its instance as MCIBg - instance names in Flash are like ID's in JavaScript - each object has an ID assigned to it to be accessible via the DOM. To place the movie clip on the timeline, you'll have to drag and drop it from the Library (Window > Library or Ctrl + L) onto the stage (stage in Flash means the working area) with the default keyframe selected. And to change the instance name, select the movie clip placed on the stage, bring up the Properties window ( Window > Properties or Ctrl + F3) and enter MCIBg in the Instance Name field.

    At this point we have the background setup that can be later altered via ActionScript. Next, we need to look at the code needed for parsing the XML document that contains the data to plot.

    Loading and Parsing the XML document
    Macromedia Flash MX provides an excellent native XML Object to deal with XML data. Using this object, one can load, send, and parse etc XML documents inside Flash. For our application, we just need to load the XML data from the URL provided to the graph (using the OBJECT/EMBED method which we had earlier seen), parse it and then use the parsed information to build the graph. Specifically, to load XML data, perform the following steps:

    1. Create a new layer named Labels. This layer is intended to contain keyframes with labels.
    2. Create three keyframes in this layer and name them as LoadXML, LoadingXML and ParseXML, respectively.
    3. Create another layer Actions and create another three keyframes in this layer also. This layer is meant to contain all ActionScripts of the movie.
    4. Now, we need to show the user some splash/loading screen while the data is being fetched from the server. So, to achieve this, create a new layer called "Loading Contents" and on the frames of this layer, place anything which you want your users to see while the data is being loaded. The picture until now should look something like:

    A sample screenshot of what your Flash designer should look like, by this point.

    Now, let's move on to render the ActionScript required for loading the XML data. First, we'll see the ActionScript required to load the XML document. The ActionScript required to load the XML data is contained in the frame LoadXML, so pop up the Actions Panel for this frame (right click on it and select Actions) and enter in the following script:

    XMLDoc = new XML();
    XMLDoc.onLoad = fnloaded;
    xmldocurl = _root.dataurl;
    
    if (xmldocurl.length < 1) {
      xmldocurl = "Data.xml";
    }
    
    XMLDoc.load(xmldocurl+"?curr="+getTimer());
    
    function fnloaded() {
      gotoAndPlay("ParseXML");
    }
    
    play();
    

    The above ActionScript first initializes an instance of the XML document, storing it in the local variable XMLDoc. We then instruct Flash that as soon as the XML document has been completely downloaded in the movie, the function fnloaded should be invoked. Next, we get the path of the XML document that has to be loaded. The path is passed to the movie by the page in which this movie is embedded as we had earlier seen using the OBJECT/EMBED method. The dataurl passed to the Flash movie from the ASP page in the format FunkyCharts.swf?dataurl=Data.asp is now accessible in Flash via _root.dataUrl.

    The following if statement, which is optional, specifies that a default XML file should be loaded in the event that no dataurl path has been provided. We invoke the load method of the XML object to load the document. We append the time at the end of the file name so that it is not cached.

    The function fnloaded, which is invoked when the XML file is loaded, simply sends the control to the ParseXML keyframe wherein the XML document will be parsed to retrieve the information. Finally, the play() command keeps the movie playing, which moves the Flash movie on to the next keyframe.

    Recall that our next keyframe is LoadingXML - the frame that is displayed until the XML document has been completely downloaded by Flash. So, in the Actions Panel of this frame, we just ask Flash to keep on playing, by adding the following one-line of ActionScript: play();.

    When the play() function is called in the LoadingXML keyframe the control is transferred to the keyframe ParseXML. In this frame, we first check if the XML document has been successfully downloaded or not. If it hasn't been downloaded, we send the control back to LoadingXML to display the loading Frames. If it has been downloaded and it doesn't contain any errors, we continue with the parsing process by invoking the custom function parseXML(); however, if there is an error in parsing the XML file we transfer the control to a keyframe XMLError, which displays an error message to the user stating that the XML received was malformed. The following ActionScript, which should be placed in the ParseXML keyframe, accomplishes these tasks:

    //If the document is loaded and it's not empty
    if (XMLDoc.loaded and XMLDoc.hasChildNodes) {
      //Check for errors in XML document
      if (XMLDoc.status == 0) {
        //If no errors present then parse it
        parseXML();
      } else {
        //If errors present, show an error message
        gotoAndPlay("XMLError");
      }
    } else {
      // If the document has not been loaded, we just send 
      // the control a li'l back to waste some time
      gotoAndPlay("LoadingXML");
    }
    

    The following function, parseXML helps in parsing the XML and retrieving the data from the XML document. Parsing the XML document using the XML object in Flash is similar to the XMLDocument() class in ASP.NET or the MSXML Parser in ASP. We have to traverse down the tree using the methods and properties exposed by the XML object.

    function parseXML() {
      //This functions parses the XML Data passed to it.
      //cldNodes array will contains the child nodes of 
      //the XML Doc passed to it.
    
      cldnodes = new Array();
      cldnodes = XMLDoc.childNodes;
    
      num = 0;
    
      dataset = new Array();
      dataname = new Array();
      datavalue = new Array();
      datacolor = new Array();
      
      for (j=0; j<=cldnodes.length; j++) {
        if (cldnodes[j].nodeName.toUpperCase() == "GRAPH") {
          bgcolor = cldnodes[j].attributes.bgcolor;
          caption = cldnodes[j].attributes.caption;
          xaxisname = cldnodes[j].attributes.xaxisname;
          yaxisname = cldnodes[j].attributes.yaxisname;
          yaxisminvalue = cldnodes[j].attributes.yaxisminvalue;
          yaxismaxvalue = cldnodes[j].attributes.yaxismaxvalue;
          dataset = cldnodes[j].childNodes;
    
          for (k=0; k<=dataset.length; k++) {
            if (dataset[k].nodeName == "set") {
              num = num+1;
              dataname[num] = dataset[k].attributes.name;
              datavalue[num] = dataset[k].attributes.value;
              datacolor[num] = dataset[k].attributes.color;
            }
          }
        }
      }
      play();
    }
    

    The parseXML() function starts by creating an array to hold the childnodes of the XML document. XMLDoc.childNodes returns a pointer to the root element of the XML document. Next, we declare a variable num to store the count of the datasets passed to the movie (via the XML document). We then iterate through the first level children of the XML Doc to search for the <graph> element.

    If the element is <graph> element, then we access the graph attributes. To access the attributes we use the attributes collection in Flash. First, we get the background color of the graph and store it in the variable bgcolor, and then the caption and so on.

    Next, we iterate through the data set. A check is made if the node name is set i.e., a graph data set. If the element is <set> then we retrieve and collect the values.

    Now, we need to make another frame in both the Actions and Labels layer. Name this frame as setDefaults. This frame will calculate the default values for the variables whose values were not supplied in the XML document. (For example, the bgcolor attribute in the <graph> element is optional; the setDefault frame will provide a default value for this attribute should it not be supplied.) Once you've created the setDefaults frame, bring up the Actions panel for this frame and enter the following ActionScript:

    // specify a default background color
    if (bgcolor == null || bgcolor == undefined || bgcolor == "") {
      bgcolor = "FFFFDD";
    }
    
    // calculate the max and min values in case the yaxisminvalue
    // and yaxismax values are not supplied
    intmin = Number(datavalue[1]);
    intmax = Number(datavalue[1]);
    for (i=2; i<=num; i++) {  
      if (Number(datavalue[i])Number(intmax)) {
        intmax = Number(datavalue[i]);
      }
    }
    
    if (yaxisminvalue == null || yaxisminvalue == undefined || 
        yaxisminvalue == "" || Number(yaxisminvalue)>Number(intmin)) {
      yaxisminvalue = Number(intmin);
    }
    
    if (yaxismaxvalue == null || yaxismaxvalue == undefined || 
        yaxismaxvalue == "" || Number(yaxismaxvalue)
    

    Now, that we have the defaults for the graph calculated and stored in variables, it's time to apply them. First, we'll see how to create the graph canvas. We'll examine how to do this in Part 3.

  • Read Part 3!


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


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