AS3 How to and Tips > The DataGrid Component

As the name suggests, the DataGrid component manages a table of data. It conveniently has methods for adding, removing and replacing entries, and it also has the ability to sort using an intuitive click on a column heading. The application below draws a simple scatter plot, a statistical graph appropriate for this data-oriented component.

Download

Download the commented (FlashCS3 compatible) fla file:

Setting up the stage

We start by placing the component on the stage: From the Components panel (Window > Components), drag an instance of the DataGrid component onto the stage, and give it the instance name dg. It does not matter where you put it — we will set its position along with its other properties in the script. Notice that we will not set anything in the Component Inspector panel at authoring time — a component can be completely customized at run time.

In addition to the component itself, you should create four new dynamic textboxes on the stage, calling them txtXmin, txtXmax, txtYmin and txtYmax. Once again, it does not matter where you place them since we intend to "attach" them at run-time to the Sprite object on which we draw the scatter plot. This alleviates any difficulties with keeping objects created on stage aligned with objects created at run-time. Of course, it is not difficult to create these as TextField objects at run-time if you prefer, but we like to keep the code in these little "how-tos" focused primarily on the subject at hand, which in this case is the use of the DataGrid component.

The only other things on the stage are the “+” and “–” buttons. These can be fashioned from a static text box atop a simple filled circle, converted to a Button at authoring time using Modify > Convert to Symbol. (You can just as easily use the playback forward and back buttons from Window > Common Libraries > Buttons, if making buttons is not your thing.) To be consistent with the script below, these buttons should have instance names btnAnother and btnRemove. The figure below shows the "active elements" of the stage setup that the script will reference:

Stage Setup

The code

// Easily accessible parameters to control size/color of board and dots:

var bSize:Number = 300;

var bColor:uint = 0xEEEECC;

var dotRadius:Number = 4;

var dotColor:uint = 0x770000;

 

// Easily accessible parameters for scatter plot scale

var xmin:Number = 0;

var xmax:Number = 100;

var ymin:Number = 0;

var ymax:Number = 100;

 

// Restrict txtNew to numbers and comma character, clear and give it focus.

txtNew.restrict = "0123456789,";

txtNew.text = "";

stage.focus = txtNew;

We create the graphBoard when the program starts. It is a Sprite since it has no timeline but we would like to be able to add other display objects as children to it .

var graphBoard:Sprite = new Sprite();

graphBoard.graphics.lineStyle(1,0x000000);

graphBoard.graphics.beginFill(bColor);

graphBoard.graphics.drawRect(0,0,bSize,bSize);

graphBoard.graphics.endFill();

 

// Add and position the graphBoard on the stage

addChild(graphBoard);

graphBoard.x = 40;

graphBoard.y = 150;

 

// Fill the textboxes and position them relative to graphBoard

txtXmin.text = String(xmin);

txtXmin.x = -txtXmin.width/2;

txtXmin.y = bSize + 5;

graphBoard.addChild(txtXmin);

 

txtXmax.text = String(xmax);

txtXmax.x = bSize - txtXmax.width/2;

txtXmax.y = bSize + 5;

graphBoard.addChild(txtXmax);

 

txtYmin.text = String(ymin);

txtYmin.x = -(txtYmin.width + 5);

txtYmin.y = bSize - 10;

graphBoard.addChild(txtYmin);

 

txtYmax.text = String(ymax);

txtYmax.x = -(txtYmax.width + 5);

txtYmax.y = -10;

graphBoard.addChild(txtYmax);

 

// The displayed points are all drawn on a single Shape object so that it can be easily cleared independently of the graphBoard.

var shPoints:Shape = new Shape();

graphBoard.addChild(shPoints);

Adding a new row is handled by the function another below.

btnAnother.addEventListener(MouseEvent.CLICK, another);

To add a new element, we parse the contents of txtNew by splitting the string at the "," delimiter. We pass this array of substrings to the isGood(…) function to see if it passes the simple tests there for validity. If it is valid, then we create newObject, a generic Object object in which the attributes xval and yval match the names given to the columns in the setup of dg at the bottom of the script. We then add this pair of numbers to the DataGrid object dg using the addItem method which takes one argument, the newObject Object containing all the "row" information. Regardless of whether the user’s new pair passes the validity test, we select the entire contents of txtNew and set focus there in preparation for either a correction or a new data pair.

function another(mevt:MouseEvent):void {

var arrNew:Array = (txtNew.text).split(",");

var newObject:Object;

if (isGood(arrNew)) {

newObject = { xval:Number(arrNew[0]), yval:Number(arrNew[1]) };

dg.addItem(newObject);

dg.scrollToIndex(dg.length-1);

drawPlot();

}

stage.focus = txtNew;

txtNew.setSelection(0,13);

}

Removing a selected row is handled by the function remove below.

btnRemove.addEventListener(MouseEvent.CLICK, remove);

The remove function below handles the removal of an element of the DataGrid using the removeItemAt method of dg, which takes one argument; namely, the index (i.e., row number) of the object to be removed. In order for this to function correctly regardless of whether something is selected, we simply check every data item in dg until (and if) we find one that is selected.

function remove(mevt:MouseEvent):void {

var i:int;

if (dg.length == 0) {

return;

}

for (i=0; i<dg.length; i++) {

if (dg.isItemSelected(dg.getItemAt(i))) {

dg.removeItemAt(i);

dg.scrollToIndex(i);

dg.clearSelection();

break;

}

}

drawPlot();

}

Several cases of input errors are checked. The program could be improved by adding a feedback textbox so the user is told what the problem is.

function isGood(arr:Array):Boolean {

if (arr.length != 2) {

return false;

}

if ((arr[0] == "") || (arr[1] == "")){

return false;

}

if ((Number(arr[0]) > xmax) || (Number(arr[0]) < xmin)) {

return false;

}

if ((Number(arr[1]) > ymax) || (Number(arr[1]) < ymin)) {

return false;

}

return true;

}

The drawPlot function is almost identical to the one in Chapter 6 of the Flash and Math Applets book, except that the data values are retrieved using a method of the DataGrid object. Specifically, dg has a method called getItemAt(index) where index is a row number in the table.

function drawPlot():void {

var i:int;

var pixX:Number,pixY:Number;

shPoints.graphics.clear();

shPoints.graphics.lineStyle(1,0);

for (i=0; i < dg.length; i++) {

// Convert from xy coordinates to screen (pixel) coordinates

pixX = bSize * (dg.getItemAt(i).xval - xmin) / (xmax - xmin);

pixY = bSize * (ymax - dg.getItemAt(i).yval) / (ymax - ymin);

 

// Draw a dot at (pixX,pixY)

shPoints.graphics.beginFill(dotColor,0.7);

shPoints.graphics.drawCircle(pixX, pixY, dotRadius);

shPoints.graphics.endFill();

}

}

Finally, we get around to setting up the DataGrid object dg. A single item in dg is an Object, which can be thought of as a completely generic ActionScript object. The constructor for the Object class is called by the reference to the list in {…} brackets (much like the […] braces are a shortcut for the Array constructor), and the properties of the Object are defined automatically by referencing them as attributes in the constructor, as shown. For example, after the following lines have been executed, a reference to sampleItem0.xval will be to the value 19.

var sampleItem0:Object = { xval:19, yval:30 };

var sampleItem1:Object = { xval:10, yval:77 };

var sampleItem2:Object = { xval:24, yval:58 };

var sampleItem3:Object = { xval:51, yval:29 };

var sampleItem4:Object = { xval:60, yval:13 };

 

dg.addItem(sampleItem0);

dg.addItem(sampleItem1);

dg.addItem(sampleItem2);

dg.addItem(sampleItem3);

dg.addItem(sampleItem4);

Now that the initial data has been placed in the DataGrid object, we can configure it more precisely. Specifically, the lines below make dg non-editable by the user at run time, make the columns sortable by a click on the top heading, place dg at x-coordinate 360, y-coordinate 190, make dg have a width of 160 pixels, make five rows show without scrolling, and set the strings that will be the names of the columns for reference purposes.

dg.editable = false;

dg.sortableColumns = true;

dg.move(360, 190);

dg.width = 160

dg.rowCount = 5;

dg.columns = ["xval", "yval"];

The application should start by plotting the sample points initially in dg, so we end the script with an explicit call to the drawPlot function.

drawPlot();

Back to AS3 How To and Tips              Back to Flash and Math Home

We welcome your comments, suggestions, and contributions. Click the Contact Us link below and email one of us.

Adobe®, Flash®, ActionScript®, Flex® are registered trademarks of Adobe Systems Incorporated.